﻿using System.Globalization;

namespace calendar1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            
            Calendar.Printdate(DateTime.Now.Year);
        }
    }
    class Calendar
    {

        const int monthHeight = 10;
        const int monthWidth = 30;
        const int dayWidth = 4;
        //输入年月日返回星期几
        private static int GetWeekByDay(int year, int month, int day)
        {
            DateTime dt = new DateTime(year, month, day);
            return (int)dt.DayOfWeek;
        }

        //输入年月返回该月天数
        private static int GetMonthDay(int year, int month)
        {
            int thismonthdays = DateTime.DaysInMonth(year, month);
            return thismonthdays;
        }
        //打印年历
        public static void Printdate(int year)
        {

            for (int month = 1; month <= 12; month++)
            {
                int x, y;
                x = ((month - 1) % 3) * monthWidth;
                y = (month - 1) / 3 * monthHeight;
                //print month title

                Console.SetCursorPosition(x, y);
                Console.WriteLine($" {month}月");
                Console.SetCursorPosition(x, y + 1);
                Console.WriteLine("  日  一  二  三  四  五  六 ");
                PrintMonth(year, month, x, y);
            }
        }

        /// <summary>
        /// print year.month at x y 
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private static void PrintMonth(int year, int month, int x, int y)
        {
            //circle around the whole month
            var theFirstDayOfMonth = new DateTime(year, month, 1);
            var FirstDayOfNextMonth = theFirstDayOfMonth.AddMonths(1);
            for (var theDay = theFirstDayOfMonth; theDay < FirstDayOfNextMonth; theDay=theDay.AddDays(1))
            {
                int xOfDay = ((int)theDay.DayOfWeek) * dayWidth + x;
                int yOfDay = weekIndexOftheDay(theDay) + y + 2;
                PrintDay(theDay.Day, xOfDay, yOfDay);
            }
        }
        
        /// <summary>
        /// 在日期前填充空格
        /// </summary>
        /// <param name="day"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private static void PrintDay(int day, int x, int y)
        {
            Console.SetCursorPosition(x, y);
            Console.Write(day.ToString().PadLeft(dayWidth, ' '));
        }

        /// <summary>
        /// return day is in which week of the month
        /// </summary>
        /// <param name="day"></param>
        /// <returns></returns>
        private static int weekIndexOftheDay(DateTime day)
        {
            if (day.Day==1)           
               return 1;
            int count = 0;

            for (int i = 1; i < day.Day; i++)
            {
                var theDay = new DateTime(day.Year, day.Month, i);
                if (theDay.DayOfWeek == DayOfWeek.Saturday)
                    count++;
            }
            return count + 1;
        }
    }
}